package com.hup.mouseIcon.presenter;

import com.hup.mouseIcon.mvp.MainMvp.MainPresenter;
import com.hup.mouseIcon.view.AppTray;
import com.hup.mouseIcon.view.MouseWindow;
import com.hup.utils.commons.exception.AppExceptionHandler;
import com.hup.utils.commons.exception.ErrInfo;
import com.hup.utils.commons.hardware.MouseUtil;
import com.hup.utils.commons.start.DialogHelper;
import com.hup.utils.commons.start.SimpleExitHandler;
import com.hup.utils.commons.start.SpringContext;
import com.hup.utils.commons.thread.ThreadPoolUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

import javax.swing.*;
import java.awt.*;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author hugan
 * @date 2020/1/4
 */
@Log4j2
@Component
public class MainPresenterImpl implements MainPresenter {

    private JWindow window;
    private ThreadPoolExecutor executor;
    private AppTray appTray;

    private boolean showMouse;

    public MainPresenterImpl() {
        executor = ThreadPoolUtil.fixedThreadExecutor("mouse-loc", 1, "鼠标移动");
        SpringContext.getBean(SimpleExitHandler.class).setExitAction(this::exitAction);
    }

    private void exitAction() {
        appTray.doHide();
        System.exit(0);
    }

    @Override
    public void startUp() {
        SwingUtilities.invokeLater(() -> {
            //需要在主线程初始化,否则window不显示?
            try {
                log.info("st");
                //log.info("isAdmin={}", SystemUtil.isAdmin());

                //MouseUtil.initRobotAble(null);//测试
                window = new MouseWindow();

                appTray = new AppTray(window);
                appTray.doShow();
                showMouse(true);
            } catch (Exception e) {
                onException(e);
            }
        });
    }

    @Override
    public void showMouse(boolean isShow) {
        try {
            log.info("isShow={}, runningCount={}", isShow, executor.getActiveCount());
            if (isShow) {
                if (executor.getActiveCount() == 0) {
                    //如果还在running,则不执行 否则会出现异常
                    executor.execute(new MouseLocRunner());
                } else {
                    log.info("触发显示时,原有进程还在运行");
                }
                showMouse = true;
                window.setVisible(true);
            } else {
                showMouse = false;
            }
        } catch (Exception e) {
            onException(e);
        }
    }

    private void onException(Exception e) {
        //一旦有异常,都是退出程序确认框
        ErrInfo errInfo = AppExceptionHandler.handle(e);
        DialogHelper.errExit(errInfo.toString()).onTop(true).show();
    }

    /**
     * 鼠标移动监听
     */
    private class MouseLocRunner implements Runnable {

        //private static final int SLEEP_SPAN = 68;
        private static final int SLEEP_SPAN = 35;

        private Point lastLoc;

        @Override
        public void run() {
            try {
                while (showMouse) {
                    Point location = MouseUtil.getLocation();
                    if (!location.equals(lastLoc)) {
                        location.x += 1;//避免挡住鼠标点击
                        log.debug("loc={}", location);
                        lastLoc = location;
                        window.setLocation(location);

                        //MouseUtil.click(location.x, location.y);//测试
                    } else {
                        log.debug("相等");
                    }
                    Thread.sleep(SLEEP_SPAN);
                }
            } catch (InterruptedException ignored) {
                Thread.currentThread().interrupt();
            } finally {
                //防止因为错误或其他情况导致线程退出
                window.setVisible(false);
                log.info("线程结束");
            }
        }
    }

}
